#ifndef OCK_MEMORY_BRIDGE_HMM_STACK_MANAGER_H
#define OCK_MEMORY_BRIDGE_HMM_STACK_MANAGER_H
#include <cstdint>
#include <utility>
#include <ostream>
#include "ock/hmm/mgr/OckHmmHMObject.h"
namespace ock {
namespace hmm {

class OckHmmStackBuffer : public OckHmmHMOBufferBase
{
public:
    virtual ~OckHmmStackBuffer() noexcept = default;
    OckHmmStackBuffer(uintptr_t addr, uint64_t length);
    OckHmmStackBuffer(const OckHmmStackBuffer &stackBuffer);
    OckHmmStackBuffer(void);
    uintptr_t Address(void) const;
    uint64_t Size(void) const;
private:
    uintptr_t addr;
    uint64_t length;
};
bool operator==(const OckHmmStackBuffer &lhs, const OckHmmStackBuffer &rhs)

class OckHmmStackManager
{
public:
    virtual ~OckHmmStackManager() noexcept = default;
    virtual OckHmmStackBuffer GetBuffer(uint64_t length, OckHmmErrorCode &errorCode) = 0;
    virtual void ReleaseBuffer(const OckHmmStackBuffer &buffer) = 0;
    static std::shared_ptr<OckHmmStackManager> Create(std::shared_ptr<OckHmmHMObject> hmo);
};

class OckHmmStackBufferGuard : public OckHmmHMOBufferBase
{
public:
    virtual ~OckHmmStackBufferGuard() noexcept;
    OckHmmStackBufferGuard(std::shared_ptr<OckHmmStackManager> stackMgr, const OckHmmStackBuffer &buffer);
    uintptr_t Address(void) const;
    uint64_t Size(void) const;
private:
    OckHmmStackBuffer buffer;
    std::shared_ptr<OckHmmStackManager> stackMgr;
};

}
}
#endif